/*
 * Copyright (C) 2012, EADS France
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package xowl.interpreter.impl;

/**
 *
 * @author Laurent WOUTERS
 */
public class VMArithmetic {
    public static xowl.lang.runtime.Literal plus(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdString) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdString)) {
            // Concatenate strings
            xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
            result.setLexicalValue(ll.getLexicalValue() + lr.getLexicalValue());
            result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdString)));
            return result;
        }
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l = Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            float res = l + r;
            xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
            result.setLexicalValue(Float.toString(res));
            result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdFloat)));
            return result;
        }
        // Add two integers
        int l = Integer.parseInt(ll.getLexicalValue());
        int r = Integer.parseInt(lr.getLexicalValue());
        int res = l + r;
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Integer.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdInteger)));
        return result;
    }
    public static xowl.lang.runtime.Literal minus(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l = Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            float res = l - r;
            xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
            result.setLexicalValue(Float.toString(res));
            result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdFloat)));
            return result;
        }
        // Add two integers
        int l = Integer.parseInt(ll.getLexicalValue());
        int r = Integer.parseInt(lr.getLexicalValue());
        int res = l - r;
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Integer.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdInteger)));
        return result;
    }
    public static xowl.lang.runtime.Literal multiply(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l = Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            float res = l * r;
            xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
            result.setLexicalValue(Float.toString(res));
            result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdFloat)));
            return result;
        }
        // Add two integers
        int l = Integer.parseInt(ll.getLexicalValue());
        int r = Integer.parseInt(lr.getLexicalValue());
        int res = l * r;
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Integer.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdInteger)));
        return result;
    }
    public static xowl.lang.runtime.Literal divide(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l = Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            float res = l / r;
            xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
            result.setLexicalValue(Float.toString(res));
            result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdFloat)));
            return result;
        }
        // Add two integers
        int l = Integer.parseInt(ll.getLexicalValue());
        int r = Integer.parseInt(lr.getLexicalValue());
        int res = l / r;
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Integer.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdInteger)));
        return result;
    }
    public static xowl.lang.runtime.Literal modulus(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        // Add two integers
        int l = Integer.parseInt(ll.getLexicalValue());
        int r = Integer.parseInt(lr.getLexicalValue());
        int res = l % r;
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Integer.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdInteger)));
        return result;
    }
    public static xowl.lang.runtime.Literal and(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        boolean l = Boolean.parseBoolean(ll.getLexicalValue());
        boolean r = Boolean.parseBoolean(lr.getLexicalValue());
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(l && r));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal or(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        boolean l = Boolean.parseBoolean(ll.getLexicalValue());
        boolean r = Boolean.parseBoolean(lr.getLexicalValue());
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(l || r));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal xor(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        boolean l =Boolean.parseBoolean(ll.getLexicalValue());
        boolean r = Boolean.parseBoolean(lr.getLexicalValue());
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(l ^ r));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal not(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll) throws xowl.interpreter.XOWLException {
        boolean l =Boolean.parseBoolean(ll.getLexicalValue());
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(!l));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal equals(xowl.interpreter.Repository repository, xowl.lang.runtime.Value left, xowl.lang.runtime.Value right) throws xowl.interpreter.XOWLException {
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        Boolean value = xowl.utils.Values.equals(left, right);
        result.setLexicalValue(value.toString());
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal different(xowl.interpreter.Repository repository, xowl.lang.runtime.Value left, xowl.lang.runtime.Value right) throws xowl.interpreter.XOWLException {
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        Boolean value = !xowl.utils.Values.equals(left, right);
        result.setLexicalValue(value.toString());
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal greater(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        boolean res = false;
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l =Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            res = l > r;
        } else {
            // Add two integers
            int l =Integer.parseInt(ll.getLexicalValue());
            int r = Integer.parseInt(lr.getLexicalValue());
            res = l > r;
        }
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal greaterEqual(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        boolean res = false;
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l =Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            res = l >= r;
        } else {
            // Add two integers
            int l =Integer.parseInt(ll.getLexicalValue());
            int r = Integer.parseInt(lr.getLexicalValue());
            res = l >= r;
        }
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal lesser(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        boolean res = false;
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l =Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            res = l < r;
        } else {
            // Add two integers
            int l =Integer.parseInt(ll.getLexicalValue());
            int r = Integer.parseInt(lr.getLexicalValue());
            res = l < r;
        }
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal lesserEqual(xowl.interpreter.Repository repository, xowl.lang.runtime.Literal ll, xowl.lang.runtime.Literal lr) throws xowl.interpreter.XOWLException {
        boolean res = false;
        if (xowl.utils.Values.isOfType(ll, OWLDatatype.xsdFloat) || xowl.utils.Values.isOfType(lr, OWLDatatype.xsdFloat)) {
            // Add two floats
            float l =Float.parseFloat(ll.getLexicalValue());
            float r = Float.parseFloat(lr.getLexicalValue());
            res = l <= r;
        } else {
            // Add two integers
            int l =Integer.parseInt(ll.getLexicalValue());
            int r = Integer.parseInt(lr.getLexicalValue());
            res = l <= r;
        }
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(Boolean.toString(res));
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdBoolean)));
        return result;
    }
    public static xowl.lang.runtime.Literal iriOf(xowl.interpreter.Repository repository, xowl.lang.runtime.Entity entity) throws xowl.interpreter.XOWLException {
        xowl.lang.runtime.Literal result = new xowl.lang.runtime.Literal();
        result.setLexicalValue(entity.getHasIRI().getHasValue());
        result.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdString)));
        return result;
    }
    public static xowl.lang.runtime.Literal lengthOf(xowl.interpreter.Repository repository, xowl.lang.runtime.Array array) throws xowl.interpreter.XOWLException {
        Integer length = array.getAllElements().size();
        xowl.lang.runtime.Literal literal = new xowl.lang.runtime.Literal();
        literal.setLexicalValue(length.toString());
        literal.setMemberOf(repository.interpretAsDatatype(repository.resolveEntity(OWLDatatype.xsdInteger)));
        return literal;
    }
}
